<template>
    <div class="courtInfo bs">
        <pageContainer ref="container" @current-page="handleCurrent" :total="total">
            <template #button>
                <el-button type="primary" plain @click="add" class="btn">新增</el-button>
                <el-button type="danger" plain @click="del()" class="btn">批量删除</el-button>
            </template>
            <template #table>
                <el-table
                  ref="multipleTableRef"
                  :data="tableData"
                  row-key="id"
                  style="width: 100%"
                  @selection-change="selectChange"
                >
                  <el-table-column type="selection" width="30" />
                  <el-table-column prop="courtName" label="球场名称" width="110" />
                  <el-table-column prop="courtImg" label="球场图片" width="120">
                    <template #default="scope">
                      <div style="display: flex; align-items: center; gap: 8px; cursor: pointer;" @click="previewImg(scope.row.courtImg, 0)">
                        <!-- 首张缩略图 -->
                        <div style="width: 40px; height: 40px; border-radius: 4px; overflow: hidden; flex-shrink: 0;">
                          <el-image :src="scope.row.courtImg[0].url" fit="cover" style="width: 100%; height: 100%;" />
                        </div>
                        <!-- 数量提示 -->
                        <span style="font-size: 12px; color: #666;">共 {{ scope.row.courtImg.length }} 张</span>
                      </div>
                    </template>
                  </el-table-column>

                  <el-table-column prop="categoryName" label="球场类型" width="90" />
                  <el-table-column prop="openTime" label="开放时间" width="104" show-overflow-tooltip/>
                  <el-table-column prop="maxPeople" label="容纳人数" width="80" />
                  <el-table-column prop="facility" label="设施" width="105" show-overflow-tooltip/>
                  <el-table-column label="状态" width="80" >
                        <template #default="scope">
                          <el-tag :type="scope.row.isMaintain=='正常'?'success':'warning'">{{scope.row.isMaintain}}</el-tag>
                        </template>
                  </el-table-column>
                  <el-table-column  label="操作" width="104">
                        <template #default="scope">
                            <el-button type="primary" :icon="Edit" circle plain @click="edit(scope.row,scope.$index)"></el-button>
                            <el-button type="danger" :icon="Delete" circle plain @click="del(scope.row,scope.$index)"></el-button>
                        </template>
                  </el-table-column>
                </el-table>
            </template>
        </pageContainer>

        <!-- 新增或修改 -->
        <el-dialog v-model="dialogFormVisible" :title="title" width="600" :lock-scroll="false" class="custom-dialog" top="26px">
            <div class="dialog-content">
              <el-form :model="formModel" :rules="rules" ref="form" hide-required-asterisk>
                <el-form-item label="球场名称"  prop="courtName">
                  <el-input v-model="formModel.courtName" autocomplete="off" />
                </el-form-item>
                <el-form-item label="球场图片"  prop="courtImg">
                  <el-upload
                    v-model:file-list="formModel.courtImg"
                    :action="uploadAction"  
                    list-type="picture-card"
                    :on-preview="previewImg"
                    :on-change="handleUpload"
                    :auto-upload="false"
                    :limit="4"
                    :on-exceed="handleExceed"
                  >
                    <el-icon><Plus /></el-icon>
                  </el-upload>
                </el-form-item>
                <el-form-item label="球场类型"  prop="categoryId">
                  <el-select v-model="formModel.categoryId" placeholder="类型" style="width: 100%">
                    <el-option
                      v-for="item in categoryOptions"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-select>
                </el-form-item>
                <el-form-item label="开放时间" prop="openTime">
                  <el-time-select
                    v-model="startTime"
                    style="width: 240px"
                    :max-time="endTime"
                    placeholder="开始时间"
                    start="08:00"
                    step="1:00"
                    end="22:00"
                  />
                  <el-time-select
                    v-model="endTime"
                    style="width: 240px;margin-left: 9px;"
                    :min-time="startTime"
                    placeholder="结束时间"
                    start="08:00"
                    step="1:00"
                    end="22:00"
                  />
                </el-form-item>
                <el-form-item label="容纳人数" prop="maxPeople">
                  <el-input v-model="formModel.maxPeople" autocomplete="off"  />
                </el-form-item>
                <el-form-item label="球场设施" prop="facility">
                  <el-input v-model="formModel.facility" autocomplete="off" />
                </el-form-item>
                <el-form-item label="球场状态" prop="isMaintain">
                  <el-select v-model="formModel.isMaintain" placeholder="状态" style="width: 100%">
                    <el-option
                      v-for="item in stateOptions"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-select>
                </el-form-item>
              </el-form>
            </div>
            <template #footer>
              <div class="dialog-footer">
                <el-button @click="dialogFormVisible = false">取消</el-button>
                <el-button type="primary" @click="confirm">
                  确定
                </el-button>
              </div>
            </template>
          </el-dialog>

        <el-image-viewer 
          v-if="showViewer" 
          :url-list="previewImgs" 
          :initial-index="initialIndex" 
          @close="showViewer = false"
        />
    </div>
</template>

<script setup>
import { ref } from 'vue';
import pageContainer from '@/components/page-container/page-container.vue';

import {
  Edit,Delete,Plus
} from '@element-plus/icons-vue'

const tableData=ref([])
const container=ref()
const title=ref('')
const dialogFormVisible=ref(false)
const uploadAction=ref('')
const startTime = ref('')
const endTime = ref('')
const form=ref()
const total=ref(0)
const formModel=ref({
    courtName:'',
    courtImg:[],
    categoryId:'',
    openTime:'',
    maxPeople:'',
    facility:'',
    isMaintain:'',
    categoryName:''
})
const categoryOptions = ref([])
let state={
  0:"正常",
  1:"维修中"
}

console.log(state)

// 获取分类列表
const getCategoryData=async ()=>{
  const res=await getCatalogList()
  console.log(res)
  res.data.data.map(item=>{
    const obj={}
    obj.value=item.categoryId
    obj.label=item.categoryName
    categoryOptions.value.push(obj)
  })
}

getCategoryData()


const stateOptions = ref([
  { label: '正常',value: 0},
  { label: '维护中',value: 1}
])

// 表单验证规则
const rules={
    courtName: [
      { required: true, message: '请输入球场名称', trigger: 'blur' },
      { min: 2, max: 20, message: '球场名称长度在 2 到 20 个字符之间', trigger: 'blur' }
    ],
    courtImg: [
      { required: true, message: '请上传至少一张球场图片', trigger: 'change' },
      { 
        validator: (rule, value, callback) => {
          if (value.length === 0) {
            callback(new Error('请上传至少一张球场图片'));
          } else if (value.length > 4) {
            callback(new Error('最多只能上传4张图片'));
          } else {
            callback();
          }
        },
        trigger: 'blur'
      }
    ],
    categoryId: [
      { required: true, message: '请选择球场类型', trigger: 'blur' }
    ],
    openTime: [
      { 
        validator: (rule, value, callback) => {
          // 验证开始时间和结束时间都已选择且合理
          if (!startTime.value) {
            callback(new Error('请选择开放开始时间'));
          } else if (!endTime.value) {
            callback(new Error('请选择开放结束时间'));
          } else if (startTime.value >= endTime.value) {
            callback(new Error('开始时间不能晚于结束时间'));
          } else {
            // 验证通过后同步到formModel
            formModel.value.openTime = `${startTime.value} - ${endTime.value}`;
            callback();
          }
        },
        trigger: ['blur']
      }
    ],
    maxPeople: [
      { required: true, message: '请输入容纳人数', trigger: 'blur' },
      //判断是否为有效数字（支持字符串格式）
      { 
        validator: (rule, value, callback) => {
          const num = Number(value); // 尝试转为数字
          if (isNaN(num)) { // 若无法转为数字（如输入字母）
            callback(new Error('容纳人数必须为数字'));
          } else {
            callback(); // 验证通过
          }
        },
        trigger: 'blur'
      },
      { 
        validator: (rule, value, callback) => {
          const num = Number(value);
          if (num < 1) {
            callback(new Error('容纳人数不能小于1人'));
          } else if (num > 1000) {
            callback(new Error('容纳人数不能超过1000人'));
          } else {
            callback();
          }
        },
        trigger: 'blur'
      }
    ],
    facility: [
      { required: true, message: '请输入球场设施', trigger: 'blur' },
      { min: 2, max: 100, message: '设施描述长度在 2 到 100 个字符之间', trigger: 'blur' }
    ],
    isMaintain: [
      { required: true, message: '请选择球场状态', trigger: 'blur' }
    ]
}

const params=ref({
  current:1,
  pageSize:4
})

const handleCurrent=(e)=>{
  console.log(e)
  params.value.current=e
}
// 获取球场数据
// const getData=async()=>{
//     const {data:{data}}=await getCourtInfo(params)
//     total.value=data.total
    
//     data.records.map(item=>{
//       // 把courtImg字符串转为数组
//       const list=item.courtImg.split(",")
//       item.courtImg=list
//       // 把数字转为字符串，0为正常，1为维修
//       item.isMaintain=state[item.isMaintain]
//     })
//     tableData.value=data.records

//     console.log(data.records)
// }

// 获取球场数据
const getData=async()=>{
    const {data:{data}}=await getCourtInfo(params)
    total.value=data.total
    
    data.records.map(item=>{
      // 把courtImg字符串转为对象，因为el-upload 组件要求 file-list 必须是「包含 uid、name、url 等属性的文件对象数组」
      const list=item.courtImg.split(",")
      const fileList = list.map(url => {
        // 从 URL 中提取文件名（如 "38d0bad0-7aa2-4279-b9b3-a7946f710ab2.jpg"）
        const fileName = url.substring(url.lastIndexOf('/') + 1); 
        return {
          uid: Date.now() + Math.random().toString(36).substr(2, 9), // 生成唯一uid（无需和后端一致）
          name: fileName, 
          url: url, // 图片预览URL（后端返回的URL）
          status: 'success', // 标记为“已上传成功”（避免组件显示“上传中”状态）
          raw: null //有留着的必要，当文件重新上传时，可以判断，详见handleUpload 
        };
      });
      item.courtImg=fileList
      // 把数字转为字符串，0为正常，1为维修
      item.isMaintain=state[item.isMaintain]
    })
    tableData.value=data.records

    console.log(data.records)
}

getData()

// 初始化
const init=()=>{
    formModel.value={
        courtName:'',
        courtImg:[],
        categoryId:'',
        openTime:'',
        maxPeople:'',
        facility:'',
        isMaintain:''
    }
    startTime.value=''
    endTime.value=''
}

// 新增球场信息
const add=()=>{
   title.value='新增'
   init()
   dialogFormVisible.value=true
}

// 编辑球场信息
const edit=(row,index)=>{
   formModel.value={...row}
   startTime.value=row.openTime.split('-')[0]
   endTime.value=row.openTime.split('-')[1]
   title.value='编辑'
   dialogFormVisible.value=true
}

// 删除球场信息
const del=()=>{
    container.value.open()
}

const showViewer = ref(false); // 是否显示预览器
const previewImgs = ref([]); // 预览的图片数组
const initialIndex = ref(0); // 预览起始索引

// 预览图片：接收图片数组和当前点击的索引
const previewImg = (imgArr, idx) => {
  previewImgs.value = imgArr;
  initialIndex.value = idx;
  showViewer.value = true;
};


// 上传处理
const handleUpload=(file)=>{

    // 跳过已回显的文件对象（status为success的是回显的，无需再处理）
    if (file.status === 'success') return;

    const reader=new FileReader()
    reader.readAsDataURL(file.raw)
    reader.onload=(e)=>{
      const fileInfo = {
        uid: file.uid, 
        name: file.name, 
        url: e.target.result, // 预览地址
        raw: file.raw, // 原始文件对象（用于后续上传）
        status: 'ready'
      }
      // 去重处理，避免重复添加
      const existingIndex = formModel.value.courtImg.findIndex(item => item.uid === file.uid)
      if (existingIndex > -1) {
        //找到索引为 existingIndex 的位置,从这个位置删除 1 个元素（即删除旧的文件信息）,在同一个位置插入新的 fileInfo 对象（即替换为新的文件信息）
        formModel.value.courtImg.splice(existingIndex, 1, fileInfo)
      } else {
        formModel.value.courtImg.push(fileInfo)
      }
    }
      console.log(formModel.value.courtImg)

}

// 是函数API，非UI组件，需单独导入
import { ElMessage } from 'element-plus'
import { getCatalog, getCatalogList } from '@/api/category';
import { addCourtInfo, getCourtInfo, updateCourtInfo } from '@/api/courtInfo';

// 超出4张则错误提醒
const handleExceed=()=>{
  if(formModel.value.courtImg.length>=4){
      ElMessage({
        message: '最多可上传4张',
        type: 'error',
      })
  }
}

// 表单提交
const confirm=async ()=>{
    await form.value.validate()  //预校验

    const formData=new FormData()
    //把formModel的东西拷到formData里面
    const textFields = ["courtName", "categoryId", "openTime", "maxPeople", "facility", "isMaintain"];
    textFields.forEach(item=>{
      formData.append(item,formModel.value[item])
    })
    // 处理图片文件：提取 raw 属性（仅新选择/修改的文件有 raw，回显的文件 raw 为 null）
    formModel.value.courtImg.forEach(file => {
      if (file.raw) { // 只传递有原始文件对象的（即新上传的）
        formData.append('courtImg', file.raw);
      }
    });
    // 发送添加请求
    if(title.value==='新增'){
      const res=await addCourtInfo(formData)
      console.log(res)
    }else{
      const res=await updateCourtInfo(formData)
      console.log(res)
    }
    

    dialogFormVisible.value=false
}

// 多选框
const selectChange=(arr)=>{
    console.log(arr)
}
</script>

<style lang='scss' scoped>
.courtInfo{
    .btn{
        height: 24px;
        font-size: 13px;
    }
    .el-dialog{
        height: 600px;
    }
    .custom-dialog{
        font-size: 10px;
    }
    /* 弹窗内容区：核心样式 */
    .dialog-content {
      max-height: 300px; 
      overflow-y: auto; /* 垂直方向溢出时显示滚动条 */
      overflow-x: hidden; /* 禁止水平滚动（避免表单错位） */
      padding: 10px 0; /* 上下内边距，优化视觉 */
    }

}
</style>